/*********************************************
 *
 *  Ports all the way down - patwd
 *  ------------------------------
 *
 *  pcap_foo.h
 *
 *  Copyright (C) 2012 by Sebastian Roschke (bykhee@gmail.com)
 *
 *  Pcap related functionality, i.e. functions and structures for capturing
 *  network packets. Current filtering based on SYN and ACK flags.
 *  Some of the structs borrowed from: http://www.tcpdump.org/pcap.html
 *
 *  Distributed under the terms and conditions of GNU LGPL.
 *
 */

#include <pcap.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>

#include "types.h"

#define ETHERNET_HEADER 14
#define SLL_HEADER 16

pcap_t *handle;
s32 linkl;

char errbuf[PCAP_ERRBUF_SIZE];

extern u8* dev;
extern u8** ips;
extern u32 ips_cnt;

void syn_mode_cfg();
void syn_mode_sniffing();

extern void handle_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

int (*get_lh_size) (void*, const struct pcap_pkthdr *hdr);

int get_ethh_size (void*, const struct pcap_pkthdr *hdr);
int get_sllh_size (void*, const struct pcap_pkthdr *hdr);

/********************************************
 * 
 * Following stuff is mostly borrowed from:
 *   - http://www.tcpdump.org/
 *
 * Thx.
 *
 ********************************************/

#define EXTRACT_16BITS(p) \
        ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \
                     (u_int16_t)*((const u_int8_t *)(p) + 1)))

/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN_SNIFF	6

/* Ethernet header */
struct sniff_ethernet {
  u_char ether_dhost[ETHER_ADDR_LEN_SNIFF]; /* Destination host address */
  u_char ether_shost[ETHER_ADDR_LEN_SNIFF]; /* Source host address */
  u_short ether_type; /* IP? ARP? RARP? etc */
};

/* IP header */
struct sniff_ip {
  u_char ip_vhl; /* version << 4 | header length >> 2 */
  u_char ip_tos; /* type of service */
  u_short ip_len; /* total length */
  u_short ip_id; /* identification */
  u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
  u_char ip_ttl; /* time to live */
  u_char ip_p; /* protocol */
  u_short ip_sum; /* checksum */
  struct in_addr ip_src, ip_dst; /* source and dest address */
};

#define IP_HL(ip)		(((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)		(((ip)->ip_vhl) >> 4)

typedef u_int32_t       tcp_seq;

/* TCP header */
struct sniff_tcp {
  u_short th_sport; /* source port */
  u_short th_dport; /* destination port */
  tcp_seq th_seq; /* sequence number */
  tcp_seq th_ack; /* acknowledgement number */

  u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th)	(((th)->th_offx2 & 0xf0) >> 4)
  u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
  u_short th_win; /* window */
  u_short th_sum; /* checksum */
  u_short th_urp; /* urgent pointer */
};
